﻿using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace TESTCommons.Encrypt
{
    #region 将普通字符串转成MD5字符串
    /// <summary>
    /// 将普通字符串转成MD5字符串
    /// </summary>
    public static class MD5Provider
    {
        public static string Hash(string message)
        {
            if (string.IsNullOrEmpty(message))
            {
                return string.Empty;
            }
            else
            {
                MD5 md5 = MD5.Create();
                byte[] source = Encoding.UTF8.GetBytes(message);
                byte[] result = md5.ComputeHash(source);
                StringBuilder buffer = new StringBuilder(result.Length);

                for (int i = 0; i < result.Length; i++)
                {
                    if (result[i].ToString("x").Length < 2)
                    {
                        buffer.Append("0" + result[i].ToString("x"));
                    }
                    else
                        buffer.Append(result[i].ToString("x"));
                }

                return buffer.ToString();
            }
        }

        #region 加密和解密
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="str">要加密的字符串</param>
        /// <returns></returns>
        public static string MD5Encrypt(string str)
        {
            //定義Md5密碼服務類 
            MD5CryptoServiceProvider mdcpValu = new MD5CryptoServiceProvider();
            //將傳入的值轉換成UTF8格式。便於加密時的格式統一
            byte[] bDestination = Encoding.UTF8.GetBytes(str);
            //加密
            byte[] bDestinationMd5 = mdcpValu.ComputeHash(bDestination);
            //將加密后的值賦給字符串
            string asDestination = "";
            foreach (byte bVal in bDestinationMd5)
                asDestination += bVal.ToString();
            return asDestination;
        }

        /// <summary>
        /// DES加密方法
        /// </summary>
        /// <param name="strPlain">明文</param>
        /// <param name="strDESKey">密钥</param>
        /// <param name="strDESIV">向量</param>
        /// <returns>密文</returns>
        public static string Encode(string source, string _DESKey)
        {
            StringBuilder sb = new StringBuilder();
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                byte[] key = ASCIIEncoding.ASCII.GetBytes(_DESKey);
                byte[] iv = ASCIIEncoding.ASCII.GetBytes(_DESKey);
                byte[] dataByteArray = Encoding.UTF8.GetBytes(source);
                des.Mode = System.Security.Cryptography.CipherMode.CBC;
                des.Key = key;
                des.IV = iv;
                string encrypt = "";
                using (MemoryStream ms = new MemoryStream())
                using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(dataByteArray, 0, dataByteArray.Length);
                    cs.FlushFinalBlock();
                    encrypt = Convert.ToBase64String(ms.ToArray());
                }
                return encrypt;
            }
        }

        /// <summary>
        /// 进行DES解密。
        /// </summary>
        /// <param name="pToDecrypt">要解密的base64串</param>
        /// <param name="sKey">密钥，且必须为8位。</param>
        /// <returns>已解密的字符串。</returns>
        public static string Decode(string source, string sKey)
        {
            try
            {
                byte[] inputByteArray = System.Convert.FromBase64String(source);//Encoding.UTF8.GetBytes(source);
                using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
                {
                    des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
                    des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
                    System.IO.MemoryStream ms = new System.IO.MemoryStream();
                    using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(inputByteArray, 0, inputByteArray.Length);
                        cs.FlushFinalBlock();
                        cs.Close();
                    }
                    string str = Encoding.UTF8.GetString(ms.ToArray());
                    ms.Close();
                    return str;
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
        }
        #endregion 
    }
    #endregion

    public class EncryptionProvider
    {
        public static string Key = "DKMAB5DE";
        private string Tk = "y6&(*jkP87jH7";

        protected string DeString(string encryptString)
        {
            string str = encryptString;
            int length = str.Length;
            int index = str.IndexOf("+");
            string s = str.Substring(0, index);
            string str3 = str.Substring(index + 1, (length - index) - 1);
            int num3 = int.Parse(s);
            string text = str3.Substring(0, str3.Length - num3);
            return this.ReverseString(text).Replace("Nhoye0ecf$", "1").Replace("T1r&@q", "5").Replace("67qjfp_", "4").Replace("Jtdp", "8").Replace("Gc&^%fds", "9");
        }

        protected string EnString(string encryptString)
        {
            string text = "";
            text = encryptString.Replace("1", "Nhoye0ecf$").Replace("5", "T1r&@q").Replace("4", "67qjfp_").Replace("8", "Jtdp").Replace("9", "Gc&^%fds");
            text = this.ReverseString(text);
            int num = new Random().Next();
            return (num.ToString().Length.ToString() + "+" + text + num.ToString());
        }

        public string MD5Decrypt(string pToDecrypt)
        {
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            byte[] buffer = new byte[pToDecrypt.Length / 2];
            for (int i = 0; i < (pToDecrypt.Length / 2); i++)
            {
                int num2 = Convert.ToInt32(pToDecrypt.Substring(i * 2, 2), 0x10);
                buffer[i] = (byte)num2;
            }
            provider.Key = Encoding.ASCII.GetBytes(Key);
            provider.IV = Encoding.ASCII.GetBytes(Key);
            MemoryStream stream = new MemoryStream();
            CryptoStream stream2 = new CryptoStream(stream, provider.CreateDecryptor(), CryptoStreamMode.Write);
            stream2.Write(buffer, 0, buffer.Length);
            stream2.FlushFinalBlock();
            StringBuilder builder = new StringBuilder();
            string encryptString = Encoding.ASCII.GetString(stream.ToArray());
            return this.DeString(encryptString);
        }

        public string MD5Encrypt(string pToEncrypt)
        {
            string s = this.EnString(pToEncrypt);
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            byte[] bytes = Encoding.Default.GetBytes(s);
            provider.Key = Encoding.ASCII.GetBytes(Key);
            provider.IV = Encoding.ASCII.GetBytes(Key);
            MemoryStream stream = new MemoryStream();
            CryptoStream stream2 = new CryptoStream(stream, provider.CreateEncryptor(), CryptoStreamMode.Write);
            stream2.Write(bytes, 0, bytes.Length);
            stream2.FlushFinalBlock();
            StringBuilder builder = new StringBuilder();
            foreach (byte num in stream.ToArray())
            {
                builder.AppendFormat("{0:X2}", num);
            }
            builder.ToString();
            return builder.ToString();
        }

        private string ReplaceString(string text)
        {
            return text.Replace("1", "@").Replace("2", "*").Replace("3", "a").Replace("5", "phi").Replace("6", "k*").Replace("8", "e").Replace("9", "mh").Replace("0", "q3");
        }

        private string ReverseStr(string text)
        {
            char[] array = text.ToCharArray();
            Array.Reverse(array);
            return new string(array);
        }

        private string ReverseString(string text)
        {
            return new string(text.ToCharArray().Reverse<char>().ToArray<char>());
        }

        public string RSADecrypt(string decryptString)
        {
            CspParameters parameters = new CspParameters
            {
                KeyContainerName = this.Tk
            };
            RSACryptoServiceProvider provider = new RSACryptoServiceProvider(parameters);
            int num = decryptString.Length / 2;
            byte[] rgb = new byte[num];
            for (int i = 0; i < num; i++)
            {
                string str = decryptString.Substring(i * 2, 2);
                rgb[i] = Convert.ToByte(str, 0x10);
            }
            rgb = provider.Decrypt(rgb, true);
            string encryptString = Encoding.ASCII.GetString(rgb);
            return this.DeString(encryptString);
        }

        public string RSAEncrypt(string encryptString)
        {
            string s = this.EnString(encryptString);
            CspParameters parameters = new CspParameters
            {
                KeyContainerName = this.Tk
            };
            byte[] buffer = new RSACryptoServiceProvider(parameters).Encrypt(Encoding.ASCII.GetBytes(s), true);
            string str2 = "";
            foreach (byte num in buffer)
            {
                str2 = str2 + string.Format("{0:x2}", num);
            }
            return str2;
        }
    }
}
